package com.app.utils;

import com.app.pojo.MyFile;
import com.app.pojo.MyPath;
import com.app.utils.bean.MFile;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.Transaction;

import java.util.Date;
import java.util.List;

@Component
public class MFileTools {

    private static final String DIR_FLAG = "/";
    @Autowired
    JedisPool jedisPool;

    /**
     * 创建文件夹
     * @return 文件夹存在或者失败则返回 false
     */
    public boolean mkDir(MFile mFile) {
        String dir = mFile.getParent();
        String path = mFile.getPath();
        try (Jedis jedis = jedisPool.getResource()) {
            if (jedis.exists(path)) return false;
            if (jedis.exists(dir)) {
                Transaction multi = jedis.multi();//使用事物
                multi.rpush(path, ":"  + new Date().getTime());
                multi.rpush(path);
                multi.exec();
                return true;
            }
        }
        return false;
    }

    /**
     * 创建文件夹,路径中所有文件夹
     * @return 文件夹存在或者失败则返回 false
     */
    public boolean mkDirs(MFile mFile){
        try (Jedis jedis = jedisPool.getResource()) {
            String[] dirnames=mFile.getPath().split("/");
            String root=dirnames[0];
            Transaction multi = jedis.multi();//使用事物
            boolean flag=false;
            long data=new Date().getTime();
            for (int i=1 ;i<dirnames.length;++i){
                if (flag||!jedis.exists(root+"/"+dirnames[i])){
                    multi.rpush(root+"/"+dirnames[i], ":" + dirnames[i] + "|" + + data);
                    multi.rpush(root,"/"+dirnames[i]);
                    flag=true;
                }
                root+="/"+dirnames[i];
            }
            multi.exec();
            return true;
        }catch (Exception e){
            e.printStackTrace();
            return false;
        }
    }
    /**
     * 删除虚拟文件，如果删除的是目录且不为空，则删除失败
     *  会以全目录为键删除。
     * 并删除将以 文件父目录 为键的列表 list 中的 改文件名、
     * 注意：不能删除根目录！
     */
    public boolean delete(MFile mFile){
        try (Jedis jedis = jedisPool.getResource()) {
            String type = jedis.type(mFile.getPath());
            String flag;
            String path = mFile.getPath();
            //是文件还是文件夹
            if ("string".equals(type)) flag="";
            else if ("list".equals(type)){//是文件夹，文件夹是否为空
                if (jedis.lrange(path, 0,1).size()>1)
                    return false;
                flag=DIR_FLAG;
            }else return false;//不存在
            //删除
            Transaction multi = jedis.multi();//使用事物
            multi.lrem(mFile.getParent(), 0,flag+mFile.getName());
            multi.del(mFile.getPath());
            multi.exec();
            multi.close();
            return true;
        }catch (Exception e){
            e.printStackTrace();
            return false;
        }
    }
    /**
     * 删除虚拟文件，如果删除的是目录，则连同目录中的所有文件都删除
     *  会以全目录为键删除。
     * 并删除将以 文件父目录 为键的列表 list 中的 改文件名、
     * 注意：不能删除根目录！
     */
    public boolean deleteAll(MFile mFile){
//        System.out.println("delete :"+myFile);/***********打印***********/
        try (Jedis jedis = jedisPool.getResource()) {
            if (jedis.exists(mFile.getPath()))
                doDelAll(mFile.getPath(),mFile.getName(),jedis);
            else return false;
            return true;
        }
    }
    //递归删除
    private void doDelAll(String dir, String filename,Jedis jedis){
        String pathname=dir+"/"+filename;
        String type = jedis.type(pathname);
        //删除的是目录
        if ("list".equals(type)){
            List<String> li = jedis.lrange(pathname,1,-1);
            if (li.size()>0){//目录中有文件
                for (String child : li)//先删除目录下所有文件
                    doDelAll(pathname,child.replace(DIR_FLAG,""),jedis);
            }
        }
        String flag = "string".equals(type)? "":DIR_FLAG;
        //删除当前
        Transaction multi = jedis.multi();//使用事物
        multi.lrem(dir,0,flag+filename);
        multi.del(pathname);
        multi.exec();
        multi.close();
    }
}
